#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gmssl/sm2.h>
#include <gmssl/sm4.h>

typedef struct {
    uint8_t iv[SM4_BLOCK_SIZE];           // IV
    uint8_t ciphertext[1024];             // SM4加密的密文
    size_t ciphertext_len;                // 密文长度
    uint8_t encrypted_key[1024];          // SM2加密的SM4密钥
    size_t encrypted_key_len;             // 加密密钥长度
    uint8_t signature[1024];              // 数字签名
    size_t signature_len;                 // 签名长度
} DigitalEnvelope;

void print_hex(const char *label, const uint8_t *data, size_t len) {
    printf("%s (%zu bytes): ", label, len);
    for(size_t i = 0; i < len; i++) {
        printf("%02X", data[i]);
    }
    printf("\n");
}

int main() {
    // 1. 读取Bob的私钥
    SM2_KEY bob_private_key;
    FILE *priv_file = fopen("bob_private_key.bin", "rb");
    if (!priv_file) {
        perror("无法打开Bob私钥文件");
        return EXIT_FAILURE;
    }
    fread(&bob_private_key, sizeof(SM2_KEY), 1, priv_file);
    fclose(priv_file);
    
    // 2. 读取Alice的公钥
    SM2_KEY alice_public_key;
    FILE *pub_file = fopen("alice_public_key.bin", "rb");
    if (!pub_file) {
        perror("无法打开Alice公钥文件");
        return EXIT_FAILURE;
    }
    fread(&alice_public_key, sizeof(SM2_KEY), 1, pub_file);
    fclose(pub_file);
    
    // 3. 读取数字信封
    DigitalEnvelope envelope;
    FILE *env_file = fopen("digital_envelope.bin", "rb");
    if (!env_file) {
        perror("无法打开数字信封文件");
        return EXIT_FAILURE;
    }
    fread(&envelope, sizeof(DigitalEnvelope), 1, env_file);
    fclose(env_file);
    
    printf("收到数字信封:\n");
    print_hex("IV", envelope.iv, SM4_BLOCK_SIZE);
    print_hex("密文", envelope.ciphertext, envelope.ciphertext_len);
    print_hex("加密的SM4密钥", envelope.encrypted_key, envelope.encrypted_key_len);
    print_hex("数字签名", envelope.signature, envelope.signature_len);
    
    // 4. 验证签名 - 使用正确的SM2_VERIFY_CTX
    SM2_VERIFY_CTX verify_ctx;  // 修正：使用SM2_VERIFY_CTX而不是SM2_SIGN_CTX
    sm2_verify_init(&verify_ctx, &alice_public_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH);
    sm2_verify_update(&verify_ctx, envelope.ciphertext, envelope.ciphertext_len);
    
    if (sm2_verify_finish(&verify_ctx, envelope.signature, envelope.signature_len) == 1) {
        printf("✓ 签名验证成功\n");
    } else {
        printf("✗ 签名验证失败\n");
        return EXIT_FAILURE;
    }
    
    // 5. 解密SM4密钥
    uint8_t sm4_key[SM4_KEY_SIZE];
    size_t sm4_key_len = sizeof(sm4_key);
    
    if (sm2_decrypt(&bob_private_key, envelope.encrypted_key, envelope.encrypted_key_len, sm4_key, &sm4_key_len) != 1) {
        fprintf(stderr, "SM2解密失败\n");
        return EXIT_FAILURE;
    }
    
    if (sm4_key_len != SM4_KEY_SIZE) {
        fprintf(stderr, "解密后的SM4密钥长度不正确\n");
        return EXIT_FAILURE;
    }
    
    print_hex("解密得到的SM4密钥", sm4_key, SM4_KEY_SIZE);
    
    // 6. SM4解密密文 - 使用信封中的IV
    SM4_KEY dec_key;
    sm4_set_decrypt_key(&dec_key, sm4_key);
    
    uint8_t decrypted[1024];
    size_t decrypted_len = sizeof(decrypted);
    
    printf("使用IV进行SM4解密: ");
    print_hex("", envelope.iv, SM4_BLOCK_SIZE);
    
    if (sm4_cbc_padding_decrypt(&dec_key, envelope.iv, envelope.ciphertext, envelope.ciphertext_len, decrypted, &decrypted_len) != 1) {
        fprintf(stderr, "SM4解密失败\n");
        return EXIT_FAILURE;
    }
    
    // 7. 输出解密结果
    printf("解密后的明文 (%zu bytes): ", decrypted_len);
    fwrite(decrypted, 1, decrypted_len, stdout);
    printf("\n");
    
    // 8. 保存解密结果
    FILE *result_file = fopen("decrypted_plain.txt", "wb");
    if (!result_file) {
        perror("无法打开结果文件");
        return EXIT_FAILURE;
    }
    fwrite(decrypted, 1, decrypted_len, result_file);
    fclose(result_file);
    
    printf("解密结果已保存至: decrypted_plain.txt\n");
    
    return EXIT_SUCCESS;
}
